# -*- coding: utf-8 -*-

"""剑指 Offer II 028. 展平多级双向链表
多级双向链表中，除了指向下一个节点和前一个节点指针之外，它还有一个子链表指针，可能指向单独的双向链表。这些子列表也可能会有一个或多个自己的子项，依此类推，生成多级数据结构，如下面的示例所示。
给定位于列表第一级的头节点，请扁平化列表，即将这样的多级双向链表展平成普通的双向链表，使所有结点出现在单级双链表中。

示例 1：
输入：head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]
输出：[1,2,3,7,8,11,12,9,10,4,5,6]
解释：
输入的多级列表如下图所示：
扁平化后的链表如下图：

示例 2：
输入：head = [1,2,null,3]
输出：[1,3,2]
解释：
输入的多级列表如下图所示：
  1---2---NULL
  |
  3---NULL

示例 3：
输入：head = []
输出：[]

如何表示测试用例中的多级链表？

以 示例 1 为例：
 1---2---3---4---5---6--NULL
         |
         7---8---9---10--NULL
             |
             11--12--NULL
序列化其中的每一级之后：
[1,2,3,4,5,6,null]
[7,8,9,10,null]
[11,12,null]
为了将每一级都序列化到一起，我们需要每一级中添加值为 null 的元素，以表示没有节点连接到上一级的上级节点。

[1,2,3,4,5,6,null]
[null,null,7,8,9,10,null]
[null,11,12,null]
合并所有序列化结果，并去除末尾的 null 。

[1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12] 

提示：

节点数目不超过 1000
1 <= Node.val <= 10^5"""


# Definition for a Node.
class Node:
    def __init__(self, val=0, prev=None, next=None, child=None):
        self.val = val
        self.prev = prev
        self.next = next
        self.child = child

class Solution:
    """深度优先的递归遍历"""
    def flatten(self, head: Node) -> Node:
        p = head
        while p:
            if p.child:
                child, follow = p.child, p.next
                p.child = None
                flattened = self.flatten(child)
                p.next = flattened
                flattened.prev = p
                while p.next:
                    p = p.next
                p.next = follow
                if follow:
                    follow.prev = p
            p = p.next
        return head


def show_node(head):
    while head:
        print(head.val, end=',')
        head = head.next
    print('')

if __name__ == '__main__':
    so = Solution()
    one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve = Node(1), Node(2), Node(3), Node(4), Node(5), Node(6), Node(7), Node(8), Node(9), Node(10), Node(11), Node(12)
    one.next, two.prev = two, one
    two.next, three.prev = three, two
    three.next, four.prev = four, three
    four.next, five.prev = five, four
    five.next, six.prev = six, five

    three.child = seven
    seven.next, eight.prev = eight, seven
    eight.next, nine.prev = nine, eight
    nine.next, ten.prev = ten, nine

    eight.child = eleven
    eleven.next, twelve.prev = twelve, eleven

    show_node(so.flatten(one))

    onex, twox, threex = Node(1), Node(2), Node(3)
    onex.child = twox
    twox.child = threex

    show_node(so.flatten(onex))

